/**
 * 数学运算模块
 * @constructor CFCaculate
 * @description 调用方法：$cf.CFCaculate.函数名称
 */
class CFCaculate {
  /**
   * @private
   * @description: 获取数字的小数位长度
   * @param {number} num 传入的数字
   * @return {number} 数字小数位长度
   */
  _getDecimalDigits(num) {
    let len;
    try {
      len = num.toString().split('.')[1].length;
    } catch {
      len = 0;
    }
    return len;
  }
  /**
   * @description: 加法运算
   * @param {number} n1 数字1
   * @param {number} n2 数字2
   * @return {number} 和
   * @example
   * // 精度问题：0.1 + 0.2 = 0.30000000000000004
   * CFCaculate.add(0.1, 0.2) // 0.3
   */
  add(n1, n2) {
    // 获取小数位
    const len1 = this._getDecimalDigits(n1);
    const len2 = this._getDecimalDigits(n2);
    // 将数字扩大n倍
    const m = Math.pow(10, Math.max(len1, len2));
    const result = (n1 * m + n2 * m) / m;
    return result;
  }
  /**
   * @description: 减法运算
   * @param {number} n1 数字1
   * @param {number} n2 数字2
   * @return {number} 差
   * @example
   * // 精度问题：0.3 - 0.2 = 0.09999999999999998
   * CFCaculate.subtract(0.3, 0.2) // 0.1
   */
  subtract(n1, n2) {
    return this.add(n1, -n2);
  }
  /**
   * @description: 乘法运算
   * @param {number} n1 数字1
   * @param {number} n2 数字2
   * @return {number} 乘积
   * @example
   * // 精度问题：1500 * 1.36 = 2040.0000000000002
   * CFCaculate.multiply(1500, 1.36) // 2040
   */
  multiply(n1, n2) {
    // 获取小数位
    const len1 = this._getDecimalDigits(n1);
    const len2 = this._getDecimalDigits(n2);
    const int1 = Number(n1.toString().replace('.', ''));
    const int2 = Number(n2.toString().replace('.', ''));
    // 取整
    return (int1 * int2) / Math.pow(10, len1 + len2);
  }
  /**
   * @description: 除法运算
   * @param {number} n1 数字1
   * @param {number} n2 数字2
   * @return {number} 商
   * @example
   * // 精度问题：0.0023 / 0.00001 = 229.99999999999997
   * CFCaculate.divide(0.0023, 0.00001) // 230
   */
  divide(n1, n2) {
    // 获取小数位
    const len1 = this._getDecimalDigits(n1);
    const len2 = this._getDecimalDigits(n2);
    const int1 = Number(n1.toString().replace('.', ''));
    const int2 = Number(n2.toString().replace('.', ''));
    return (int1 / int2) * Math.pow(10, len2 - len1);
  }
  /**
   * 阶乘运算
   * @param {Number} num 自然数
   * @returns {Number} 阶乘结果
   * @example
   * CFCaculate.factorial(5); // 5 * 4 *3 * 2 * 1 = 120;
   */
  factorial(num) {
    if (num <= 1) {
      return 1;
    }
    return num * this.factorial(num - 1);
  }
}

export default CFCaculate;
